package com.ease.plugin.loaderClasses {
//	import com.hurlant.crypto.Crypto;
//	import com.hurlant.crypto.symmetric.ICipher;
  import com.ease.plugin.URLResource;
  import com.ease.plugin.events.ErrorEvent;
  import com.ease.plugin.traits.DisplayObjectTrait;
  import com.ease.plugin.traits.LoadState;
  import com.ease.plugin.traits.LoadTrait;

  import flash.display.DisplayObject;
  import flash.display.Loader;
  import flash.display.LoaderInfo;
  import flash.errors.IOError;
  import flash.events.Event;
  import flash.events.IOErrorEvent;
  import flash.events.SecurityErrorEvent;
  import flash.geom.Rectangle;
  import flash.net.URLLoader;
  import flash.net.URLLoaderDataFormat;
  import flash.net.URLRequest;
  import flash.system.ApplicationDomain;
  import flash.system.LoaderContext;
  import flash.system.SecurityDomain;
  import flash.utils.ByteArray;

  public class LoaderUtils {

    public static function createDisplayObjectTrait(loader:Loader):DisplayObjectTrait {
      var displayObject:DisplayObject = null;
      var mediaWidth:Number = 0;
      var mediaHeight:Number = 0;

      var info:LoaderInfo = loader.contentLoaderInfo;

      displayObject = loader;
      displayObject.scrollRect = new Rectangle(0, 0, info.width, info.height);

      mediaWidth = info.width;
      mediaHeight = info.height;

      return new DisplayObjectTrait(displayObject, mediaWidth, mediaHeight);
    }

    public static function loadLoadTrait(loadTrait:LoadTrait, updateLoadTraitFunction:Function,
                                           checkPolicyFile:Boolean = false, encrypted:Boolean = false):void {
      var loaderLoadTrait:LoaderLoadTrait = loadTrait as LoaderLoadTrait;

         var resource:URLResource = loadTrait.resource as URLResource;
      var urlReq:URLRequest = new URLRequest((loadTrait.resource as URLResource).url.toString());

         var loader:Loader = new Loader();
         loaderLoadTrait.loader = loader;

         updateLoadTraitFunction(loadTrait, LoadState.LOADING);

         var context:LoaderContext = new LoaderContext();
         context.checkPolicyFile = false;
         context.applicationDomain = ApplicationDomain.currentDomain;

         toggleLoaderListeners(loader, true);

         if (resource.encrypted) {
            var key:ByteArray = new ByteArray();
            key.writeUTF(resource.key);

            var binaryLoader:URLLoader = new URLLoader();
            binaryLoader.addEventListener(Event.COMPLETE, onLoadInit);

            binaryLoader.dataFormat = URLLoaderDataFormat.BINARY;
            binaryLoader.load(urlReq);

            function onLoadInit(e:Event):void {
               binaryLoader.removeEventListener(Event.COMPLETE, onLoadInit);

               var binaryData:ByteArray = new ByteArray();
               binaryData = binaryLoader.data;
               var encryptedBytes:ByteArray = new ByteArray();
               binaryData.readBytes(encryptedBytes);

               //decrypt using 128b AES encryption
//               var aes:ICipher = Crypto.getCipher("aes-ecb", key, Crypto.getPad("pkcs5"));
//               aes.decrypt(encryptedBytes);
               encryptedBytes.position = 0;
               if(encryptedBytes.length != 0) {
                  loader.loadBytes(encryptedBytes, context);
               }
            }
         }
         else {
            if (urlReq.url.search(/^file:\//i) == -1 ) {
               context.securityDomain = SecurityDomain.currentDomain;
            }
           try {
             loader.load(urlReq, context);
           }
           catch (ioError:IOError) {
             onIOError(null, ioError.message);
           }
           catch (securityError:SecurityError) {
             onSecurityError(null, securityError.message);
           }
         }

      function toggleLoaderListeners(loader:Loader, on:Boolean):void {
        if (on) {
          loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
          loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
          loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
        }
        else {
          loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoadComplete);
          loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
          loader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
        }
      }

      function onLoadComplete(event:Event):void {
        toggleLoaderListeners(loader, false);
        updateLoadTraitFunction(loadTrait, LoadState.READY);
      }

      function onIOError(ioEvent:IOErrorEvent, ioEventDetail:String=null):void {
        toggleLoaderListeners(loader, false);
        loader = null;
        updateLoadTraitFunction(loadTrait, LoadState.LOAD_ERROR);
      }

      function onSecurityError(securityEvent:SecurityErrorEvent, securityEventDetail:String=null):void {
        toggleLoaderListeners(loader, false);
        loader = null;
        updateLoadTraitFunction(loadTrait, LoadState.LOAD_ERROR);
      }
    }

    /**
     * Unloads the given LoadTrait.
     **/
    public static function unloadLoadTrait(loadTrait:LoadTrait, updateLoadTraitFunction:Function):void {
      var loaderLoadTrait:LoaderLoadTrait = loadTrait as LoaderLoadTrait;
      updateLoadTraitFunction(loadTrait, LoadState.UNLOADING);
      updateLoadTraitFunction(loadTrait, LoadState.UNINITIALIZED);
    }

    private static const SWF_MIME_TYPE:String = "application/x-shockwave-flash";

  }
}